#include "StdAfx.h"
#include "FrameArray.hxx"


FrameArray::FrameArray(void)
{
	_pageCount = 50;
    _pageSize = 1280 * 960 * 3 / 2;
    _pool = 0;

	//_flags = 0;
	//_indices = 0;

	::InitializeCriticalSection( &_keyCs );
}


FrameArray::~FrameArray(void)
{
	if( _pool ) 
		free( _pool );
	_pool = 0;

	::DeleteCriticalSection( &_keyCs );
}

void FrameArray::initialize()
{
	//_flags = new bool[ _pageCount ];
	//_indices = new int[ _pageCount ];

    if( _pool ) free( _pool );
    _pool = (char*)malloc( _pageCount * _pageSize );

    for( int i = 0; i < _pageCount; i ++ )
    {
        _flags[ i ] = false;
		_indices[ i ] = -1;
    }
}

bool FrameArray::addFrame(const char* buf, int valueIndex )
{
	bool added = false;
	for( int i = 0; i < _pageCount; i ++ )
	{
		if( !_flags[ i ] )
		{
			lock();

			_indices[ i ] = valueIndex;
			_flags[ i ] = true;
			memcpy( _pool + _pageSize * i, buf, _pageSize );

			unlock();

			added = true;

			break;
		}
	}

	if( !added )
	{
		printf(">>>> Lost a frame....\n");
	}

	return added;

}

bool FrameArray::eraseFrame( int valueIndex )
{	
	lock();
	for( int i = 0; i < _pageCount; i ++ )
	{
		if( _indices[ i ] == valueIndex )
		{
			
			_flags[ i ] = false;
			_indices[ i ] = -1;
			
		}		
	}
	unlock();
	return true;
}

bool FrameArray::eraseFrameByIndex( int index )
{	
	lock();
	_flags[ index ] = false;
	_indices[ index ] = -1;	
	unlock();
	return true;
}

char* FrameArray::getFrameByValueKey( int valueIndex )
{
	//// step 1: find key index

	char* result = 0;

	lock();

	for( int i = 0; i < _pageCount; i ++ )
	{
		if( _indices[ i ] == valueIndex )
		{
			result = _pool + i * _pageSize;
			break;
		}
	}
	
	unlock();
	return result;
}

char* FrameArray::getFrameByIndex( int index )
{
	if( index > -1 && index < _pageCount )
		return _pool + _pageSize * index;
	else
		return 0;
}

char* FrameArray::getNextFreeFrame( int& index )
{
	char* result = 0;

	lock();

	for( int i = 0; i < _pageCount; i ++ )
	{
		if( !_flags[ i ] )
		{
			index = i;
			result = _pool + i * _pageSize;
			break;
		}
	}

	unlock();

	return result;
}

void FrameArray::useFrame( int index, int frameIndex )
{
	lock();
	_flags[ index ] = true;
	_indices[ index ] = frameIndex;
	unlock();

}

void FrameArray::lock()
{
	::EnterCriticalSection( &_keyCs );
}

void FrameArray::unlock()
{
	::LeaveCriticalSection( &_keyCs );
}

void FrameArray::empty()
{
	lock();

	for( int i = 0; i < _pageCount; i ++ )
	{
		_flags[ i ] = false;
		_indices[ i ] = 0;
	}

	unlock();
}

bool FrameArray::isEmpty()
{
	bool result = true;

	for( int i = 0; i < _pageCount; i ++ )
	{
		if( _flags[ i ] )
		{
			result = false;
			break;
		}
	}

	return result;
}